package com.bidevalution.business.impl;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Service;
import com.bidevalution.business.service.JdbcTemplateService;
import com.bidevalution.dao.jdbc.JdbcTemplateSupport;
import com.bidevalution.support.exception.BizException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service
public class JdbcTemplateServiceImpl implements JdbcTemplateService {

	private final Logger logger = LoggerFactory.getLogger(JdbcTemplateServiceImpl.class);

	@Autowired
	private JdbcTemplateSupport jdbcTemplateSupport;

	public List<Map<String, Object>> selectForList(String sql, Map<String, Object> paramMap) {
		try {
			return jdbcTemplateSupport.selectForList(sql, paramMap);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return Lists.newArrayList();
		}
	}
	public void save(String sql,SqlParameterSource sqlParameterSource) {
		jdbcTemplateSupport.save(sql, sqlParameterSource);
	}

	@Override
	public <T> T selectForObject(String sql, Map<String, ?> paramMap, Class<T> requiredType) {

		try {
			return jdbcTemplateSupport.selectForObject(sql, paramMap, requiredType);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
	}

	@Override
	public <T> T selectForObject(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper) {
		try {
			return jdbcTemplateSupport.selectForObject(sql, paramMap, rowMapper);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
	}

	@Override
	public Map<String, Object> selectForMap(String sql, Map<String, Object> paramMap) {
		try {
			return jdbcTemplateSupport.selectForMap(sql, paramMap);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return null;
		}

	}

	@Override
	public <T> List<T> selectForList(String sql, Map<String, Object> paramMap, Class<T> requiredType) {
		try {
			return jdbcTemplateSupport.selectForList(sql, paramMap, requiredType);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return Lists.newArrayList();
		}
	}

	@Override
	public <T> List<T> selectForList(String sql, Map<String, Object> paramMap, RowMapper<T> rowMapper) {
		try {
			return jdbcTemplateSupport.selectForList(sql, paramMap, rowMapper);
		} catch (Exception e) {
			logger.error(e.getMessage());
			return Lists.newArrayList();
		}
	}

	/**
	 * 
	 * <p>
	 * Description:执行存储过程
	 * </p>
	 * 
	 * @param sectionStepId 环节ID
	 * @param procedureName 存储过程名称
	 * @return
	 * @see com.bidevalution.business.service.JdbcTemplateService#executeProcedure(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public Boolean executeProcedure(String procedureName, Object... values) throws Exception {
		try {
			return jdbcTemplateSupport.callProduce(procedureName, values);
 		} catch (SQLException e) {
 			if(10000 == e.getErrorCode()) {
 				throw new BizException(e.getMessage(),e);
 			}
 			throw new BizException(e.getMessage(),e);
 		}catch (Exception e) {
 			throw e;
 		}
	}

	@Override
	public void insert(String sql, Map<String, Object> paramMap) {
		jdbcTemplateSupport.insert(sql, paramMap);
	}

	@Override
	public void update(String sql, Map<String, Object> paramMap) {
		System.out.println(sql + "sqlsql" + paramMap);
		jdbcTemplateSupport.update(sql, paramMap);
	}

	@Override
	public void bathInsert(String sql, SqlParameterSource[] batchArgs) {
		jdbcTemplateSupport.bathInsert(sql, batchArgs);
	}

	@Override
	public void bathUpdate(String sql, SqlParameterSource[] batchArgs) {
		jdbcTemplateSupport.bathUpdate(sql, batchArgs);
	}

	@Override
	public void insertBean(String sql, Object bean) {
		try {
			jdbcTemplateSupport.insert(sql, convertBean(bean));
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	public static Map<String, Object> convertBean(Object bean)
			throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		Class<?> type = bean.getClass();
		Map<String, Object> returnMap = Maps.newHashMap();
		BeanInfo beanInfo = Introspector.getBeanInfo(type);

		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (!propertyName.equals("class")) {
				Method readMethod = descriptor.getReadMethod();
				Object result = readMethod.invoke(bean, new Object[0]);
				if (result != null) {
					returnMap.put(propertyName, result);
				} else {
					returnMap.put(propertyName, "");
				}
			}
		}
		return returnMap;
	}

}
